#include "MainForm.h"

#define displayState(i) AppLog("Recording state:%d", i)

using namespace Osp::Base;
using namespace Osp::Ui;
using namespace Osp::Ui::Controls;
using namespace Osp::Media;
using namespace Osp::App;
using namespace Osp::System;
using namespace Osp::Graphics;

MainForm::MainForm(void) {
}

MainForm::~MainForm(void) {
}

bool MainForm::Initialize() {
	// Construct an XML form
	Construct(L"IDF_MAINFORM");
	AppLog("Initialize()");

	return true;
}

result MainForm::OnInitializing(void) {
	result r = E_SUCCESS;

	__onColor = Osp::Graphics::Color(5, 162, 37);
	__offColor = Osp::Graphics::Color(25, 171, 51);
	// TODO: Add your initialization code here
	firstRunCheckOK = false;
	__pButton = static_cast<Button *> (GetControl(L"IDC_START"));
	if (__pButton != null)
		__pButton->AddActionEventListener(*this);
	//	pButton = static_cast<Button *> (GetControl(L"IDC_STOP"));
	//	pButton->AddActionEventListener(*this);

	//	Label *label = static_cast<Label *> (GetControl(L"IDC_FROM"));
	//	int level;
	//	Battery::GetCurrentLevelInPercentage(level);
	//	String s;
	//	s.Append(level);
	//	s.Append(L"%");
	//	label->SetText(s);
	//	label = static_cast<Label *> (GetControl(L"IDC_TO"));
	//	label->SetText(s);
	//	AppLogDebug("batter level %d", level);
	//************** Draw Image Begin
	Label *pLabel = static_cast<Label *> (GetControl(L"IDC_IMG"));
	Image *pImage = new Image();
	Bitmap *pBitmap = null;
	pImage->Construct();
	pBitmap = pImage->DecodeN(String("/Res/2012.jpg"),
			BITMAP_PIXEL_FORMAT_ARGB8888, pLabel->GetWidth(),
			pLabel->GetHeight());

	delete pImage;
	pImage = null;

	pLabel->SetBackgroundBitmap(*pBitmap);
	pLabel->RequestRedraw();
	AppLog("imageDraw");
	//************** Draw Image End

	//**************** Day
	Label *pDayLabel = static_cast<Label *> (GetControl(L"IDC_DAY"));

	DateTime dt1, dt2;
	dt2.SetValue(2012, 7, 27);
	//	dt1.SetValue(2012, 7, 26);
	SystemTime::GetCurrentTime(dt1);
	TimeSpan ts2 = dt2.GetTime();
	TimeSpan ts1 = dt1.GetTime();
	TimeSpan ts = ts2 - ts1;
	String s;
	if (ts.GetDays() >= 1) {
		s.Append(ts.GetDays());
		if (ts.GetDays() == 1)
			s.Append(L" Day To Go ");
		else
			s.Append(L" Days To Go ");
		pDayLabel->SetText(s);
	}
	//	AppLog(dt2.ToString().__pValue );
	//	AppLog("%d --dt2----", dt2.GetDay());
	//	AppLog("%d --dt2----", dt1.GetDay());
	//**************** Day End

	return r;
}

result MainForm::setupCamera() {
	AppLog("setupCamera");
	result r;
	r = E_SUCCESS;
	Osp::Base::Collection::IList *resolutionList;
	Osp::Graphics::Dimension *resolution;

	if (__pCamera != null)
		delete __pCamera;

	__pCamera = new Camera();
	if (__pCamera == null) {
		return E_FAILURE;
	}
	__pCamera->Construct(*this, CAMERA_PRIMARY);
	__pCamera->PowerOn();
	__pCamera->SetFlash(true);
	resolutionList = __pCamera->GetSupportedPreviewResolutionListN();
	if ((resolution
			= static_cast<Osp::Graphics::Dimension *> (resolutionList->GetAt(0)))
			!= null)
		__pCamera->SetPreviewResolution(*resolution);
	resolutionList->RemoveAll();
	delete resolutionList;

	r = __pCamera->StartPreview(null, false);
	AppLogDebug("Preview Resolution w:%d h:%d", resolution->width, resolution->height);
	return r;
}

result MainForm::setupRecorder() {
	AppLog("setupRecorder()");
	result r = E_SUCCESS;

	if (__pVideoRecorder != null)
		delete __pVideoRecorder;

	__pVideoRecorder = new VideoRecorder();
	if (__pVideoRecorder == null) {
		return E_FAILURE;
	}
	__pVideoRecorder->Construct(*this, *__pCamera);
	__pVideoRecorder->SetMaxRecordingSize(__bufferFileSize); // x KB
	__pVideoRecorder->CreateVideoFile(String(__bufferFile), true);
	__pVideoRecorder->SetQuality(RECORDING_QUALITY_LOW);
	__pVideoRecorder->SetMode(VIDEORECORDER_MODE_VIDEO_ONLY);
	__pVideoRecorder->SetFormat(VIDEORECORDING_FORMAT_3GP);
	Osp::Graphics::Dimension *resolution;
	resolution = new Osp::Graphics::Dimension(
			__pCamera->GetPreviewResolution().width,
			__pCamera->GetPreviewResolution().height);
	r = __pVideoRecorder->SetRecordingResolution(*resolution);
	AppLogDebug("SetRecordingResolution returns:%d", (int)r);
	//	__pVideoRecorder->SetRecordingResolution(*resolution);
	AppLogDebug("VideoRecording Resolution w:%d h:%d", __pVideoRecorder->GetRecordingResolution().width, __pVideoRecorder->GetRecordingResolution().height);
	return r;
}

result MainForm::startRecorder() {

	return __pVideoRecorder->Record();
}

result MainForm::showMessageBox(String str, bool isModel) {
	__pMessageBox = new MessageBox();
	if (isModel == true)
		__pMessageBox->Construct(L"", str, MSGBOX_STYLE_OK);
	else
		__pMessageBox->Construct(L"", str, MSGBOX_STYLE_OK, 3000);
	int r = E_SUCCESS;
	__pMessageBox->ShowAndWait(r);
	delete __pMessageBox;
	return (result) r;
}

result MainForm::firstRunCheck() {
	result r = E_SUCCESS;
	long long inSize, exSize;
	bool hasFlashLight = true;
	MediaCapability::GetValue(L"CAMERA_PRIMARY_SUPPORT_FLASH", hasFlashLight);
	AppLog("firstRunCheck()");

	if (hasFlashLight != true) {
		showMessageBox(GetString(L"IDS_NO_FLASHLIGHT"));
		//		Terminate();
		return E_FAILURE;
	}

	RuntimeInfo::GetValue(L"AvailableInternalStorage", inSize);
	RuntimeInfo::GetValue(L"AvailableExternalStorage", exSize);
	AppLogDebug("inSize:%lld, exSize:%lld", inSize, exSize);
	if (inSize / 1024 < __minBufferFileSize && exSize / 1024
			< __minBufferFileSize) {
		showMessageBox(GetString(L"IDS_MEM_NOT_ENOUGH"));
		//		Terminate();
		return E_FAILURE;
	}
	if (inSize / 1024 > __maxBufferFileSize) {
		AppLog("use __maxBufferFileSize of internal mem");
		__bufferFileSize = __maxBufferFileSize;
		__bufferFile = String(L"/Home/led.mp4");
	} else if (exSize / 1024 > __maxBufferFileSize) {
		AppLog("use __maxBufferFileSize of external mem");
		__bufferFileSize = __maxBufferFileSize;
		__bufferFile = String(L"/Storagecard/Media/Others/led.mp4");
	} else if (inSize / 1024 >= __minBufferFileSize) {
		AppLogDebug("use %d internal mem", inSize/1024);
		__bufferFileSize = inSize / 1024;
		__bufferFile = String(L"/Home/led.mp4");
	} else {
		AppLogDebug("use %d external mem", exSize/1024);
		__bufferFileSize = exSize / 1024;
		__bufferFile = String(L"/Storagecard/Media/Others/led.mp4");
	}

	r = setupCamera();
	if (r == E_FAILURE)
		AppLog("error after setup camera");//test
	if (r == E_SUCCESS) {
		r = setupRecorder();
		if (r == E_FAILURE)
			AppLog("error after setup recorder");//test
	}
	if (r != E_SUCCESS) {
		showMessageBox(GetString(L"IDS_DEVICE_BUSY"));
		//		Terminate();
		r = E_FAILURE;
	}
	return r;

}

void MainForm::OnActionPerformed(const Osp::Ui::Control &source, int actionId) {
	if (firstRunCheckOK == false) {
		firstRunCheckOK = (firstRunCheck() == E_SUCCESS ? true : false);
	}
	if (firstRunCheckOK == false) {
		AppLog("run check error");
		return;
	}

	AppLog("ActionPerformed");
	if (__pButton->GetText() == GetString("IDS_OFF")) {

		// turn on it
		AppLog("start");
		if (startRecorder() != E_SUCCESS) {
			showMessageBox(GetString(L"IDS_DEVICE_BUSY"), false);
		} else {
			__pButton->SetTextColor(__offColor);
			__pButton->SetText(GetString(L"IDS_ON"));
		}
	} else {
		// turn off it
		if (__pVideoRecorder->Pause() != E_SUCCESS) {
			showMessageBox(GetString(L"IDS_DEVICE_BUSY"), false);
		} else {
			__pButton->SetTextColor(__onColor);
			__pButton->SetText(GetString(L"IDS_OFF"));
		}
	}
}

void MainForm::OnVideoRecorderEndReached(
		Osp::Media::RecordingEndCondition endCondition) {
	result r;
	AppLog("OnVideoRecorderEndReached");
	//delete __pVideoRecorder;
	r = setupRecorder();
	if (r == E_SUCCESS) {
		r = startRecorder();
	}
	if (r != E_SUCCESS) {
		showMessageBox(GetString(L"IDS_DEVICE_BUSY"), false);
	}
}

result MainForm::OnTerminating(void) {
	result r = E_SUCCESS;
	//  Add your termination code here
	/*if (__pVideoRecorder != null)
	 delete __pVideoRecorder;
	 if (__pCamera != null)
	 delete __pCamera;*/

	return r;
}

void MainForm::OnCameraErrorOccurred(Osp::Media::CameraErrorReason err) {
	AppLog("CameraError: %d", err);
	switch (err) {
	case RECORDER_ERROR_OUT_OF_STORAGE:
		AppLog("RECORDER_ERROR_OUT_OF_STORAGE");
		break;
	case RECORDER_ERROR_STORAGE_FAILED:
		AppLog("RECORDER_ERROR_STORAGE_FAILED ");
		break;
	case RECORDER_ERROR_DEVICE_FAILED:
		AppLog("RECORDER_ERROR_DEVICE_FAILED ");
		break;
	}
}

void MainForm::OnVideoRecorderErrorOccurred(RecorderErrorReason r) {
	AppLog("VideoRecorderErrorReason:%d", r);
}

String MainForm::GetString(String id) {
	String str;
	Application::GetInstance()->GetAppResource()->GetString(id, str);
	return str;
}

void MainForm::Terminate() {
	AppLog("Terminate()");
	//	Application::GetInstance()->Terminate();
}
